package com.franklin.ideaplugin.maphelper.resolver.impl.map;

import com.franklin.ideaplugin.api.beans.declaration.IDeclaration;
import com.franklin.ideaplugin.api.beans.variable.IVariable;
import com.franklin.ideaplugin.api.utils.psi.PsiClassUtils;
import com.franklin.ideaplugin.maphelper.beans.colmember.IColMember;
import com.franklin.ideaplugin.maphelper.col.declaration.IColDeclaration;
import com.franklin.ideaplugin.maphelper.col.operation.ColOperationFactory;
import com.franklin.ideaplugin.maphelper.col.method.IColQueryMethod;
import com.franklin.ideaplugin.maphelper.col.operation.IColReadWriteOperation;
import com.franklin.ideaplugin.maphelper.utils.PsiColUtils;
import com.google.common.collect.Sets;
import com.intellij.psi.*;

import java.util.Collection;
import java.util.Objects;

/**
 * 从collection中查询出来的map
 *
 * @author Ye Junhui
 * @since 2024/3/11
 */
public class CollectionGetMapMemberResolver extends CollectionMapMemberResolver{

    public final static CollectionGetMapMemberResolver INSTANCE = new CollectionGetMapMemberResolver();

    @Override
    public boolean supports(IColDeclaration colDeclaration) {
        IDeclaration declaration = colDeclaration.getDeclaration();
        IVariable variable = declaration.getVariable();
        if (Objects.isNull(variable)) {
            return false;
        }
        //校验类型
        PsiType psiType = variable.getPsiType();
        if (!PsiClassType.class.isInstance(psiType)) {
            return false;
        }
        PsiClassType psiClassType = (PsiClassType) psiType;
        PsiClass psiClass = psiClassType.resolve();
        if (!PsiClassUtils.isJavaMapClass(psiClass)) {
            return false;
        }
        //调用方法表达式
        PsiMethodCallExpression psiMethodCallExpression = declaration.getCreateExpression(PsiMethodCallExpression.class);

        //调用者
        PsiExpression callerExpression = psiMethodCallExpression.getMethodExpression().getQualifierExpression();
        if (Objects.isNull(callerExpression)){
            return false;
        }

        //调用者类型
        PsiType callerType = callerExpression.getType();
        if (Objects.isNull(callerType) || !PsiClassType.class.isInstance(callerType)){
            return false;
        }
        PsiClassType classType = (PsiClassType) callerType;
        PsiClass callerClass = classType.resolve();
        if (!PsiClassUtils.isJavaCollectionClass(callerClass)){
            return false;
        }

        //调用方法
        PsiMethod psiMethod = psiMethodCallExpression.resolveMethod();
        if (Objects.isNull(psiMethod)){
            return false;
        }

        //寻找查询方法
        IColReadWriteOperation matchOperation = ColOperationFactory.matchOperation(
                psiMethod,
                ColOperationFactory.COLLECTION_READ_WRITE_OPERATIONS,
                colReadWriteOperation -> {
                    IColQueryMethod colQueryMethod = PsiColUtils.findColQueryMethod(psiMethod, colReadWriteOperation.getQueryMethods());
                    return Objects.nonNull(colQueryMethod);
                }
        );
        return Objects.nonNull(matchOperation);
    }

    @Override
    public Collection<IColMember> resolveColMembers(PsiElement psiExpression, IColDeclaration colDeclaration) {
        IDeclaration declaration = colDeclaration.getDeclaration();
        //调用方法表达式
        PsiMethodCallExpression psiMethodCallExpression = declaration.getCreateExpression(PsiMethodCallExpression.class);

        //调用者
        PsiExpression callerExpression = psiMethodCallExpression.getMethodExpression().getQualifierExpression();

        //调用者定义
        IColDeclaration callerDeclaration = PsiColUtils.findColExpressionDeclaration(callerExpression);
        if (Objects.isNull(callerDeclaration)){
            return Sets.newLinkedHashSet();
        }
        return super.resolveColMembers(callerExpression, callerDeclaration);
    }

}
